package com.techsoul.module.tms.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.ExcelException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.pojo.vo.OrgVo;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.DateUtils;
import com.techsoul.common.core.util.lang.StringUtils;
import com.techsoul.common.core.util.poi.ExcelImport;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.basic.mapper.*;
import com.techsoul.module.basic.pojo.entity.*;
import com.techsoul.module.basic.pojo.entity.Customer;
import com.techsoul.module.basic.pojo.param.SuspiciousItemSaveParam;
import com.techsoul.module.basic.pojo.vo.TBmLocationVo;
import com.techsoul.module.basic.pojo.vo.WarehouseVo;
import com.techsoul.module.order.pojo.entity.PurchaseOrderItem;
import com.techsoul.module.order.pojo.entity.SalesOrder;
import com.techsoul.module.pms.enmus.WmsInStatusEnum;
import com.techsoul.module.pms.enmus.WmsOutStatusEnum;
import com.techsoul.module.pms.mapper.*;
import com.techsoul.module.pms.pojo.entity.*;
import com.techsoul.module.pms.pojo.param.TbWmsMaterialReceiptLineSaveParam;
import com.techsoul.module.pms.pojo.vo.TbWmsMaterialReceiptVo;
import com.techsoul.module.pms.service.IBmsAllGeneralSeqTabService;
import com.techsoul.module.system.mapper.OrgMapper;
import com.techsoul.module.tms.mapper.TFoFreightOrderItemMapper;
import com.techsoul.module.tms.mapper.TFoFreightOrderMapper;
import com.techsoul.module.tms.pojo.entity.*;
import com.techsoul.module.tms.pojo.param.TFoFreightOrderItemSaveParam;
import com.techsoul.module.tms.pojo.param.TFoFreightOrderItemSearchParam;
import com.techsoul.module.tms.pojo.param.TFoTransitRouteSearchParam;
import com.techsoul.module.tms.pojo.vo.DispatchImportOrderItemVo;
import com.techsoul.module.tms.pojo.vo.TFoFreightOrderItemVo;
import com.techsoul.module.tms.pojo.vo.TFoTransitRouteVo;
import com.techsoul.module.tms.service.IExpressService;
import com.techsoul.module.tms.service.ITFoFreightOrderItemService;
import com.techsoul.module.tms.service.ITFoTransitRouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

/**
 * 运单明细 Service实现
 * 
 * @author liuen
 * @date 2023-05-29
 */

@Service
@Slf4j
@Transactional(readOnly = true)
public class TFoFreightOrderItemServiceImpl implements ITFoFreightOrderItemService {

    @Autowired
    private IdWorker idWorker;
    @Autowired
    private IExpressService iExpressService;
    @Autowired
    private ITFoTransitRouteService iTFoTransitRouteService;
    @Autowired
    private TFoFreightOrderItemMapper mapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private TBmLocationMapper locationmapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private IBmsAllGeneralSeqTabService tBmsAllGeneralSeqTabService;
    @Autowired
    private TbWmsMaterialReceiptNotExistMapper tbWmsMaterialReceiptNotExistMapper;
    @Autowired
    private CustomerConsigneeMapper customerConsigneeMapper;
    @Autowired
    private TFoFreightOrderMapper orderMapper;
    @Autowired
    private TbWmsMaterialDeliveryLineMapper tbWmsMaterialDeliveryLineMapper;

    @Autowired
    private TbWmsMaterialReceiptLineMapper tbWmsMaterialReceiptLineMapper;
    @Autowired
    private TbWmsMaterialReceiptMapper tbWmsMaterialReceiptMapper;
    @Autowired
    private SuspiciousItemMapper suspiciousItemMapper;
    @Autowired
    private TbWmsMaterialInLocationMapper tbWmsMaterialInLocationMapper;
    @Autowired
    private TWhWarehouseCustomerMaterialMapper tWhWarehouseCustomerMaterialMapper;
    @Autowired
    private TbWmsMaterialDeliveryMapper tbWmsMaterialDeliveryMapper;

    @Autowired
    private SuspiciousItemMapper sspiciousItemMapper;

    @Autowired
    private TokenService tokenService;

    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(TFoFreightOrderItemSaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        TFoFreightOrderItem entity = new TFoFreightOrderItem();
        BeanUtils.copyProperties(params, entity);
        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }
    @Transactional(readOnly = false)
    @Override
    public String resolveSuspicious(SuspiciousItemSaveParam param){
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        SuspiciousItem suspiciousItem =  this.suspiciousItemMapper.selectById(param.getId());
        suspiciousItem.setAction(param.getAction());
        suspiciousItem.setStatus(param.getStatus());
        suspiciousItem.preUpdate(user.getId());
        this.suspiciousItemMapper.updateById(suspiciousItem);

        if(suspiciousItem.getSuspiciousType().equals("outWarehouse")){
            TbWmsMaterialDeliveryLine item = this.tbWmsMaterialDeliveryLineMapper.selectById(param.getId());
            item.setStatus(param.getStatus());
            item.preUpdate(user.getId());
            this.tbWmsMaterialDeliveryLineMapper.updateById(item);
        }else  if(suspiciousItem.getSuspiciousType().equals("inWarehouse")){
            TbWmsMaterialReceiptLine tWmsMaterialReceiptLine = this.tbWmsMaterialReceiptLineMapper.selectById(param.getId());
            tWmsMaterialReceiptLine.setStatus(param.getStatus());
            tWmsMaterialReceiptLine.preUpdate(user.getId());
            this.tbWmsMaterialReceiptLineMapper.updateById(tWmsMaterialReceiptLine);
        }else{
            TFoFreightOrderItem tFoFreightOrderItem = this.mapper.selectById(param.getId());
            tFoFreightOrderItem.setStatus(param.getStatus());
            tFoFreightOrderItem.preUpdate(user.getId());
            this.mapper.updateById(tFoFreightOrderItem);
        }
       return "success";
    }
    @Transactional(readOnly = false)
    @Override
    public List<TFoFreightOrderItem> generateMoveTrDispatch
            (List<TbWmsMaterialReceipt> deliverys,List<TbWmsMaterialReceiptLine> items,
             TFoFreightOrderItemSaveParam params, UserVo sysUser, List<TFoFreightOrder> orders,String moveToWarehouse,
             List<Map<String,String>> tbWmsMaterialReceiptsMap){
        String rt = "success";
        List<TFoFreightOrderItem> dispatchItems = new ArrayList<TFoFreightOrderItem>();
        TBmLocationVo departloc =new TBmLocationVo();

        TBmLocationVo destloc =new TBmLocationVo();
        for(int i=0;i<deliverys.size();i++){
            TbWmsMaterialReceipt tbWmsMaterialDelivery= (TbWmsMaterialReceipt)deliverys.get(i);
            TbWmsMaterialReceiptLine tbWmsMaterialDeliveryLineVo=
                    (TbWmsMaterialReceiptLine)items.get(i);
            TFoFreightOrder order =  new TFoFreightOrder();
            String orderNo = tBmsAllGeneralSeqTabService.generateNo("freightOrder");

            order.setOrderNo("WMS".concat(orderNo));
            order.setCustomerNo(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            order.setCompanyName(sysUser.getCompanyName());
            order.setCompanyNo(sysUser.getCustomerId());
            order.setConsigneeAddress(tbWmsMaterialDeliveryLineVo.getConsigneeAddress());
            // order.setConsigneeLinkMan(tbWmsMaterialDeliveryVo.get);
            order.setConsigneeMobilePhone(tbWmsMaterialDeliveryLineVo.getConsigneePhoneNo());
            order.setConsigneeNo(tbWmsMaterialDeliveryLineVo.getConsigneeNo());
            Warehouse warehouse = this.warehouseMapper.
                    selectById(tbWmsMaterialReceiptsMap.get(i).get(tbWmsMaterialDelivery.getId()));
            if(warehouse==null){
                OrgVo thisOrg = this.orgMapper.findById(sysUser.getOrgId());
                warehouse =this.warehouseMapper.
                        findByCode(thisOrg.getWarehouseCode());
            }

            Warehouse deliverywarehouse = this.warehouseMapper.
                    selectById(moveToWarehouse);
            Customer cust = this.customerMapper.selectById(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            order.setDepartmentNo(sysUser.getOrgId());
            if(deliverywarehouse.getCity()!=null&&deliverywarehouse.getProvince()!=null&&deliverywarehouse.getDistrict()!=null){
                order.setDestination(deliverywarehouse.getProvince().concat(",").
                        concat(deliverywarehouse.getCity()).concat(",").concat(deliverywarehouse.getDistrict()));
                order.setDestinationName(deliverywarehouse.getWarehouserName());
                if(deliverywarehouse.getAddress()!=null){
                    order.setDestPortAddress(deliverywarehouse.getWarehouserName()+"-"+deliverywarehouse.getAddress());
                }else{
                    order.setDestPortAddress(deliverywarehouse.getWarehouserName());
                }

            }//else if(cust.getLocationCode()!=null){
            // order.setDestination(cust.getLocationCode());
            //order.setDestinationName(cust.getDistrict());
            //order.setDestPortAddress(cust.getAddress());
            //}
            if(warehouse.getCity()!=null&&warehouse.getProvince()!=null&&warehouse.getDistrict()!=null){
                order.setDeparture(warehouse.getProvince().concat(",").
                        concat(warehouse.getCity()).concat(",").concat(warehouse.getDistrict()));
                order.setDepartureName(warehouse.getWarehouserName());

                if(deliverywarehouse.getAddress()!=null){
                    order.setDepartPortAddress(warehouse.getWarehouserName()+"-"+warehouse.getAddress());
                }else{
                    order.setDepartPortAddress(warehouse.getAddress());
                }
            }
            order.setCarrierTime(new Date());

            order.setShipperAddress(cust.getAddress());
            order.setShipperName(cust.getCustomerName());
            order.setShipperPhone(cust.getContactPhone());
            order.setIsHotYn(params.getIsHotYn());

            order.setSourceOrderId(tbWmsMaterialDelivery.getId());
            order.setSourceOrderNo(tbWmsMaterialDelivery.getOrderNo());

            order.setServiceType(params.getServiceType());

            order.setOrderTypeNo(params.getOrderTypeNo()); //LTl ftl
            order.setOrderDate(new Date());
            order.setFreightOrderNo(orderNo);
            order.setStatus("created");
            order.setVehicleModelNo(tbWmsMaterialDeliveryLineVo.getVehicleModel());
            order.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            order.setFreightOrderNo(orderNo);
            this.orderMapper.insert(order);
            orders.add(order);
            TFoFreightOrderItem tFoFreightOrderItem = new TFoFreightOrderItem();
            BeanUtils.copyProperties(tbWmsMaterialDeliveryLineVo,tFoFreightOrderItem);

            tFoFreightOrderItem.setCargoFreightNo(tbWmsMaterialDeliveryLineVo.getMaterialNo());
            tFoFreightOrderItem.setCargoFreightName(tbWmsMaterialDeliveryLineVo.getMaterialName());
            // 图号
            tFoFreightOrderItem.setSkuCode(tbWmsMaterialDeliveryLineVo.getSkuCode());

            tFoFreightOrderItem.setShipByPackOrqty(tbWmsMaterialDeliveryLineVo.getShipByPackOrqty());


            tFoFreightOrderItem.setOrderFrNo(tbWmsMaterialDeliveryLineVo.getOrderNo());
            tFoFreightOrderItem.setConsigneeName(tbWmsMaterialDeliveryLineVo.getCustomerName());
            tFoFreightOrderItem.setConsignee(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            tFoFreightOrderItem.setConsigneeAddress(tbWmsMaterialDeliveryLineVo.getConsigneeAddress());
            tFoFreightOrderItem.setConsigneeLinkman(cust.getContactName());
            tFoFreightOrderItem.setConsigneePhone(cust.getContactPhone());

            tFoFreightOrderItem.setConsigneeLinktype(cust.getCustomerType());
            tFoFreightOrderItem.setSkuCode(tbWmsMaterialDeliveryLineVo.getSkuCode());
            //tFoFreightOrderItem.setConsigneeReceiveQuantity();
            tFoFreightOrderItem.setSettledBasedOn(tbWmsMaterialDeliveryLineVo.getShipByPackOrqty());


            tFoFreightOrderItem.setCompanyNo(sysUser.getCustomerId());

            tFoFreightOrderItem.setEstDeliveryDate(new Date());
            tFoFreightOrderItem.setEstDepartTm(order.getCarrierTime());
            tFoFreightOrderItem.setDepartPort(order.getDepartPort());

            tFoFreightOrderItem.setDeparture(order.getDeparture());
            tFoFreightOrderItem.setDepartureAddr(order.getDepartPortAddress());
            tFoFreightOrderItem.setFreightOrderNo(order.getFreightOrderNo());
            tFoFreightOrderItem.setDestination(order.getDestination());
            tFoFreightOrderItem.setDestinationAddr(order.getDestPortAddress());
            tFoFreightOrderItem.setOrderFromSource(tbWmsMaterialDelivery.getOrderNo());

            tFoFreightOrderItem.setStatus("created");
            tFoFreightOrderItem.setOrderTypeNo(order.getOrderTypeNo());

            String serviceType= "moveWarehouse" ;

            tFoFreightOrderItem.setServiceType(serviceType);
            tFoFreightOrderItem.setDeliveryType(order.getServiceType());
            tFoFreightOrderItem.setFreightOrderId(order.getId());
            tFoFreightOrderItem.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            tFoFreightOrderItem.setDestination(order.getDestination());
            tFoFreightOrderItem.setDeparture(order.getDeparture());

            tFoFreightOrderItem.setCargoFreightNo(tbWmsMaterialDeliveryLineVo.getMaterialNo());
            tFoFreightOrderItem.setCargoFreightName(tbWmsMaterialDeliveryLineVo.getMaterialName());
            tFoFreightOrderItem.setContainerNo(tbWmsMaterialDeliveryLineVo.getId());//入库单明细号
         //   tFoFreightOrderItem.setCauseNo(tbWmsMaterialDeliveryLineVo.getCaseNo()); // 出库单明细号
            tFoFreightOrderItem.setDropOffWarehouseNo(deliverywarehouse.getId());
            tFoFreightOrderItem.setWarehouseCd(warehouse.getId());
            this.mapper.insert(tFoFreightOrderItem);
            dispatchItems.add(tFoFreightOrderItem);

        }

        return  dispatchItems;
    }
    @Transactional(readOnly = false)
    @Override
    public List<TFoFreightOrderItem> generateMoveDispatch
            (List<TbWmsMaterialDelivery> deliverys, List<TbWmsMaterialDeliveryLine> items,
             TFoFreightOrderItemSaveParam params, UserVo sysUser, List<TFoFreightOrder> orders,String moveToWarehouseNo){
        String rt = "success";
        List<TFoFreightOrderItem> dispatchItems = new ArrayList<TFoFreightOrderItem>();
        TBmLocationVo departloc =new TBmLocationVo();

        TBmLocationVo destloc =new TBmLocationVo();
        for(int i=0;i<deliverys.size();i++){
            TbWmsMaterialDelivery tbWmsMaterialDelivery= (TbWmsMaterialDelivery)deliverys.get(i);
            TbWmsMaterialDeliveryLine tbWmsMaterialDeliveryLineVo=
                    (TbWmsMaterialDeliveryLine)items.get(i);
            TFoFreightOrder order =  new TFoFreightOrder();
            String orderNo = tBmsAllGeneralSeqTabService.generateNo("freightOrder");

            order.setOrderNo("WMS".concat(orderNo));
            order.setCustomerNo(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            order.setCompanyName(sysUser.getCompanyName());
            order.setCompanyNo(sysUser.getCustomerId());
            order.setConsigneeAddress(tbWmsMaterialDelivery.getConsigneeAddress());
            // order.setConsigneeLinkMan(tbWmsMaterialDeliveryVo.get);
            order.setConsigneeMobilePhone(tbWmsMaterialDelivery.getConsigneePhoneNo());
            order.setConsigneeNo(tbWmsMaterialDelivery.getConsignee());
            Warehouse warehouse = this.warehouseMapper.
                    selectById(tbWmsMaterialDelivery.getWarehouseCode());
            if(warehouse==null){
                OrgVo thisOrg = this.orgMapper.findById(sysUser.getOrgId());
                warehouse =this.warehouseMapper.
                        findByCode(thisOrg.getWarehouseCode());
            }

            Warehouse deliverywarehouse = this.warehouseMapper.
                    selectById(moveToWarehouseNo);
            Customer cust = this.customerMapper.selectById(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            order.setDepartmentNo(sysUser.getOrgId());
            if(deliverywarehouse.getCity()!=null&&deliverywarehouse.getProvince()!=null&&deliverywarehouse.getDistrict()!=null){
                order.setDestination(deliverywarehouse.getProvince().concat(",").
                        concat(deliverywarehouse.getCity()).concat(",").concat(deliverywarehouse.getDistrict()));
                order.setDestinationName(deliverywarehouse.getWarehouserName());
                order.setDestPortAddress(deliverywarehouse.getAddress());
            }//else if(cust.getLocationCode()!=null){
               // order.setDestination(cust.getLocationCode());
                //order.setDestinationName(cust.getDistrict());
                //order.setDestPortAddress(cust.getAddress());
            //}
            if(warehouse.getCity()!=null&&warehouse.getProvince()!=null&&warehouse.getDistrict()!=null){
                order.setDeparture(warehouse.getProvince().concat(",").
                        concat(warehouse.getCity()).concat(",").concat(warehouse.getDistrict()));
                order.setDepartureName(warehouse.getWarehouserName());
                order.setDepartPortAddress(warehouse.getAddress());
            }
            order.setCarrierTime(tbWmsMaterialDelivery.getPreDeliveryTime());

            order.setShipperAddress(cust.getAddress());
            order.setShipperName(cust.getCustomerName());
            order.setShipperPhone(cust.getContactPhone());
            order.setIsHotYn(params.getIsHotYn());

            order.setSourceOrderId(tbWmsMaterialDelivery.getId());
            order.setSourceOrderNo(tbWmsMaterialDelivery.getOrderNo());

            order.setServiceType(params.getServiceType());

            order.setOrderTypeNo(params.getOrderTypeNo()); //LTl ftl
            order.setOrderDate(new Date());
            order.setFreightOrderNo(orderNo);
            order.setStatus("created");
            order.setVehicleModelNo(tbWmsMaterialDeliveryLineVo.getVehicleModel());
            order.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            order.setFreightOrderNo(orderNo);
            this.orderMapper.insert(order);
            orders.add(order);
            TFoFreightOrderItem tFoFreightOrderItem = new TFoFreightOrderItem();
            BeanUtils.copyProperties(tbWmsMaterialDeliveryLineVo,tFoFreightOrderItem);

            tFoFreightOrderItem.setCargoFreightNo(tbWmsMaterialDeliveryLineVo.getMaterialNo());
            tFoFreightOrderItem.setCargoFreightName(tbWmsMaterialDeliveryLineVo.getMaterialName());
            // 图号
            tFoFreightOrderItem.setSkuCode(tbWmsMaterialDeliveryLineVo.getSkuCode());

            tFoFreightOrderItem.setShipByPackOrqty(tbWmsMaterialDeliveryLineVo.getShipByPackOrqty());
            if(tbWmsMaterialDeliveryLineVo.getCargoValue()!=null){
                tFoFreightOrderItem.setCargoValue
                        (BigDecimal.valueOf(tbWmsMaterialDeliveryLineVo.getCargoValue()));

            }

            tFoFreightOrderItem.setOrderFrNo(tbWmsMaterialDeliveryLineVo.getOrderNo());
            tFoFreightOrderItem.setConsigneeName(tbWmsMaterialDeliveryLineVo.getCustomerName());
            tFoFreightOrderItem.setConsignee(tbWmsMaterialDeliveryLineVo.getCustomerNo());
            tFoFreightOrderItem.setConsigneeAddress(tbWmsMaterialDeliveryLineVo.getConsigneeAddress());
            tFoFreightOrderItem.setConsigneeLinkman(cust.getContactName());
            tFoFreightOrderItem.setConsigneePhone(cust.getContactPhone());

            tFoFreightOrderItem.setConsigneeLinktype(cust.getCustomerType());
            tFoFreightOrderItem.setSkuCode(tbWmsMaterialDeliveryLineVo.getSkuCode());
            //tFoFreightOrderItem.setConsigneeReceiveQuantity();
            tFoFreightOrderItem.setSettledBasedOn(tbWmsMaterialDeliveryLineVo.getShipByPackOrqty());

            tFoFreightOrderItem.setPalletQty(tbWmsMaterialDeliveryLineVo.getPalletQty());
            tFoFreightOrderItem.setCompanyNo(sysUser.getCustomerId());
            if(!StringUtils.isNull(tbWmsMaterialDeliveryLineVo.getRequestDeliveryTime())){
                Date esta = DateUtils.parseDate(tbWmsMaterialDeliveryLineVo.getRequestDeliveryTime());
                tFoFreightOrderItem.setEstDeliveryDate(esta);
            }

            tFoFreightOrderItem.setEstDepartTm(order.getCarrierTime());
            tFoFreightOrderItem.setDepartPort(order.getDepartPort());

            tFoFreightOrderItem.setDeparture(order.getDeparture());
            tFoFreightOrderItem.setDepartureAddr(order.getDepartPortAddress());
            tFoFreightOrderItem.setFreightOrderNo(order.getFreightOrderNo());
            tFoFreightOrderItem.setDestination(order.getDestination());
            tFoFreightOrderItem.setDestinationAddr(order.getDestPortAddress());
            tFoFreightOrderItem.setOrderFromSource(tbWmsMaterialDelivery.getOrderNo());

            tFoFreightOrderItem.setStatus("created");
            tFoFreightOrderItem.setOrderTypeNo(order.getOrderTypeNo());

            String serviceType= "moveWarehouse" ;

            tFoFreightOrderItem.setServiceType(serviceType);
            tFoFreightOrderItem.setDeliveryType(order.getServiceType());
            tFoFreightOrderItem.setFreightOrderId(order.getId());
            tFoFreightOrderItem.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            tFoFreightOrderItem.setDestination(order.getDestination());
            tFoFreightOrderItem.setDeparture(order.getDeparture());

            tFoFreightOrderItem.setCargoFreightNo(tbWmsMaterialDeliveryLineVo.getMaterialNo());
            tFoFreightOrderItem.setCargoFreightName(tbWmsMaterialDeliveryLineVo.getMaterialName());
            tFoFreightOrderItem.setContainerNo(tbWmsMaterialDeliveryLineVo.getReceivedLineId());//入库单明细号
            tFoFreightOrderItem.setCauseNo(tbWmsMaterialDeliveryLineVo.getCaseNo()); // 出库单明细号
            tFoFreightOrderItem.setDropOffWarehouseNo(deliverywarehouse.getId());
            tFoFreightOrderItem.setWarehouseCd(warehouse.getId());
            this.mapper.insert(tFoFreightOrderItem);
            dispatchItems.add(tFoFreightOrderItem);

        }

        return  dispatchItems;
    }

    @Transactional(readOnly = false)
    @Override
    public String confirm(String id){
        TFoFreightOrderItem item = this.mapper.selectById(id);
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        item.setStatus(WmsOutStatusEnum.confirmed.getValue());
        item.preUpdate(user.getId());
        this.mapper.updateById(item);

        return item.getId();
    }
    @Transactional(readOnly = false)
    @Override
    public String moveToSuspicious(TFoFreightOrderItemSaveParam param){
        TFoFreightOrderItem item = this.mapper.selectById(param.getId());
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        item.setStatus(WmsOutStatusEnum.suspicious.getValue());
        item.preUpdate(user.getId());
         this.mapper.updateById(item);
        SuspiciousItem suspiciousItem = new SuspiciousItem();
        suspiciousItem.setDesc(param.getDesc());
        suspiciousItem.setSuspiciousType("freight");
        suspiciousItem.setOrderNo(item.getId());
        suspiciousItem.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.sspiciousItemMapper.insert(suspiciousItem);
        return suspiciousItem.getId();
    }
    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(TFoFreightOrderItemSaveParam params) {
        TFoFreightOrderItem entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public TFoFreightOrderItemVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<TFoFreightOrderItemVo> findAll(TFoFreightOrderItemSearchParam params) {
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<TFoFreightOrderItemVo> findAll(TFoFreightOrderItemSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }

    @Override
    @Transactional(readOnly = false)
    public String importData1(MultipartFile file) {
        List<DispatchImportOrderItemVo> dataList = null;
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        int successNum = 0;
        int failureNum = 0;
        int logNum = 0;
        try {
            ExcelImport excelImport = new ExcelImport(file, 1, 0);
            dataList = excelImport.getDataList(DispatchImportOrderItemVo.class);
        } catch (Exception e) {
            log.error("获取数据信息失败!");
            throw new ExcelException("获取数据信息失败!");
        }
        if (ListUtils.isEmpty(dataList)) {
            throw new ExcelException("导入数据不能为空！");
        }

        if(dataList==null||dataList.size()==0){
            //return "没有读取到数据";
            log.error("没有读取到数据!");
        }

        String custOrderNo ="";
        SalesOrder newSalesOrder = null;
        int itemNo = 0;
        int line = 0;
        TbWmsMaterialReceiptLineSaveParam entity = new TbWmsMaterialReceiptLineSaveParam();
        for (DispatchImportOrderItemVo data : dataList) {
            successNum++;
            line++;

            TbWmsMaterialReceiptVo tbWmsMaterialReceipt= this.tbWmsMaterialReceiptMapper.findByVinNo(data.getVinNo());

            if(tbWmsMaterialReceipt==null){
                continue;
            }


            tbWmsMaterialReceipt.getItemList().get(0).setCarrier(data.getCarrier());
            tbWmsMaterialReceipt.getItemList().get(0).setCarrierNo(data.getCarrierNo());
            TbWmsMaterialReceiptLine entity1 = new TbWmsMaterialReceiptLine();
            BeanUtils.copyProperties(tbWmsMaterialReceipt.getItemList().get(0), entity1);

            this.tbWmsMaterialReceiptLineMapper.updateById(entity1);
        }

        successMsg.insert(0, "入库单已更新承运商！共 " + successNum + " 条");


        return successMsg.toString();
    }



    @Override
    @Transactional(readOnly = false)
    public String importDataWithCarrier(MultipartFile file) {
        List<DispatchImportOrderItemVo> dataList = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        Integer successNum = 0;
        Integer failureNum = 0;
        String str = "";
        try {
            ExcelImport excelImport = new ExcelImport(file, 1, 0);
            dataList = excelImport.getDataList(DispatchImportOrderItemVo.class);
        } catch (Exception e) {
            log.error("获取数据信息失败!");
            throw new ExcelException("获取数据信息失败!");
        }
        if (ListUtils.isEmpty(dataList)) {
            throw new ExcelException("导入数据不能为空！");
        }
        for (DispatchImportOrderItemVo data : dataList) {
            try {
                PurchaseOrderItem ent = new PurchaseOrderItem();
                org.springframework.beans.BeanUtils.copyProperties(data, ent);
                ent.setVehicleLoadType(data.getVehicleLoadType());
                ent.setConsigneeName(data.getConsigneeName());
                // 验证数据是否已经出库
                TbWmsMaterialDeliveryLine line = this.tbWmsMaterialDeliveryLineMapper.findBySapOrderNo(data.getPickupVoucherList(), data.getVinNo());
                // 验证入库里是否存在
                TbWmsMaterialReceiptVo receiptVo= this.tbWmsMaterialReceiptMapper.findByVinNo(data.getVinNo());


                if (line == null && receiptVo ==null) {
                    this.saveToExceptions(data, ent, sysUser);
                    continue;
                }
                TFoTransitRouteVo routVo= this.getCarrier(data);
                if(routVo==null){
                    String msg = "<br/>导入失败：承运商" + data.getCarrierName() + "，没有配置路线;";
                    successMsg.append(msg);
                    break;
                }

                WarehouseVo warehouseVo = this.warehouseMapper.findById(routVo.getWarehouseId());

                //新增出库单。并修改入库单状态和库存状态
                if(receiptVo!=null && line == null ){
                    str = this.saveToDelivery(data, sysUser,receiptVo);
                }
                // 外借或者维修无法出库
                if(str.equals("no")){
                    continue;
                }
                //remodel 委改厂
                //去往包装厂的车辆
                if(warehouseVo.getWarehouseType().equals("packing")){

                }


                //String rt=  this.iExpressService.importDataWithCarrier(data,ent,sysUser,successNum,failureNum);
                successMsg.append("");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、订单号 " + data.getPurchaseOrderNo() + " 导入失败：";
                successMsg.append(msg + e.getMessage());
                log.error(msg, e);
                successMsg.append(msg + e.getMessage());

            }
        }



        return successMsg.toString();
    }

    @Override
    @Transactional(readOnly = false)
    public void saveToExceptions(DispatchImportOrderItemVo data,PurchaseOrderItem ent,UserVo sysUser){
        TbWmsMaterialReceiptNotExist tbWmsMaterialReceiptNotExist = new TbWmsMaterialReceiptNotExist();

        com.techsoul.common.core.util.bean.BeanUtils.copyProperties(ent,tbWmsMaterialReceiptNotExist);
        com.techsoul.common.core.util.bean.BeanUtils.copyProperties(data,tbWmsMaterialReceiptNotExist);
        tbWmsMaterialReceiptNotExist.setDeliveryNo(data.getPickupVoucherList());
        tbWmsMaterialReceiptNotExist.setOrderNo(data.getPurchaseOrderNo());
        tbWmsMaterialReceiptNotExist.setVinNo(data.getVinNo());
        tbWmsMaterialReceiptNotExist.setId( idWorker.nextId() + "" ).preInsert(sysUser.getId());
        this.tbWmsMaterialReceiptNotExistMapper.insert(tbWmsMaterialReceiptNotExist);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateToDelivery(UserVo user,TbWmsMaterialReceiptVo receiptVo, TbWmsMaterialDeliveryLine line){

        TbWmsMaterialDelivery delivery = this.tbWmsMaterialDeliveryMapper.selectById(line.getDeliveryId());
        delivery.setStatus(WmsInStatusEnum.outPlaned.getValue());
        delivery.setUpdateBy(user.getId());
        this.tbWmsMaterialDeliveryMapper.updateById(delivery);

        line.setStatus(WmsInStatusEnum.outPlaned.getValue());
        line.setUpdateBy(user.getId());
        this.tbWmsMaterialDeliveryLineMapper.updateById(line);


        receiptVo.getItemList().get(0).setStatus(WmsInStatusEnum.outPlaned.getValue());
        receiptVo.getItemList().get(0).setUpdateBy(user.getId());
        TbWmsMaterialReceiptLine line1 = new TbWmsMaterialReceiptLine();
        BeanUtils.copyProperties(receiptVo.getItemList().get(0), line1);
        tbWmsMaterialReceiptLineMapper.updateById(line1);


        TbWmsMaterialReceipt receipt = new TbWmsMaterialReceipt();
        BeanUtils.copyProperties(receiptVo, receipt);
        receipt.setStatus(WmsInStatusEnum.outPlaned.getValue());
        receipt.preUpdate(user.getId());
        this.tbWmsMaterialReceiptMapper.updateById(receipt);
    }

    @Override
    @Transactional(readOnly = false)
    public String saveToDelivery(DispatchImportOrderItemVo data,UserVo user,TbWmsMaterialReceiptVo receiptVo){
        // 查询库存信息
        List<TbWmsMaterialInLocation> tbWmsMaterialInLocationList = this.tbWmsMaterialInLocationMapper.findByReciptLineId(receiptVo.getItemList().get(0).getId());

        // 如果库存处于外借或者维修状态 无法出库。
        if(!tbWmsMaterialInLocationList.get(0).getStatus().equals("inposition")){
            return "no";
        }

        TWhWarehouseCustomerMaterial tWhWarehouseCustomerMaterial = this.tWhWarehouseCustomerMaterialMapper.findByMaterialNoAndCustomerNo(data.getMaterialNo(),data.getCustomerNo());
        if(tWhWarehouseCustomerMaterial==null){
            tWhWarehouseCustomerMaterial = new TWhWarehouseCustomerMaterial();
            BeanUtils.copyProperties(data, tWhWarehouseCustomerMaterial);
            tWhWarehouseCustomerMaterial.setMaterialNo(data.getMaterialNo());
            tWhWarehouseCustomerMaterial.setVehicleModel(data.getMaterialNo());
            tWhWarehouseCustomerMaterial.setMeasUnitNo("辆");
            tWhWarehouseCustomerMaterial.setId(idWorker.nextId() + "").preInsert(user.getId());
            this.tWhWarehouseCustomerMaterialMapper.insert(tWhWarehouseCustomerMaterial);
        }

        WarehouseVo warehouse  = warehouseMapper.findByName(data.getPickUpWarehouseNo());
        String warehouseId = null;
        String [] str =  this.convertDetailAddressToPCD(data.getPickUpAddress());
        TBmLocationVo tBmLocationVo= this.locationmapper.findBytreeName(str[0]+"/"+str[1]+"/"+str[2]);
        if(StringUtils.isNull(warehouse)){
            Warehouse warehouse1 = new Warehouse();
            //BeanUtils.copyProperties(warehouse, warehouse1);
            warehouse1.setWarehouserCode("code");
            warehouse1.setWarehouserName(data.getPickUpWarehouseNo());
            warehouse1.setWarehouseType(data.getPickUpWarehouseNo().contains("中心库")?"center":"remodel");
            if(str.length>0){
                String [] s = tBmLocationVo.getTreeIds().split(",");
                warehouse1.setProvince(s[0]);
                warehouse1.setCity(s[1]);
                warehouse1.setDistrict(s[2]);
            }
            warehouse1.setAddress(data.getPickUpAddress());
            warehouse1.setId(idWorker.nextId() + "").preInsert(user.getId());
            warehouseMapper.insert(warehouse1);
            warehouseId = warehouse1.getId();
        }else{
            warehouseId = warehouse.getId();
        }
        CustomerConsignee customerConsignee = this.customerConsigneeMapper.findByCode(data.getCollectionUnit());
        if(customerConsignee==null){
            customerConsignee = new CustomerConsignee();
            customerConsignee.setCustomerNo(data.getCollectionUnit());
            customerConsignee.setCcccode(data.getCollectionUnit());
            customerConsignee.setWarehouseCode(warehouseId);
            customerConsignee.setConsigneeName(data.getConsigneeName());
            customerConsignee.setConsigneeAddress(data.getDeliveryAddress());
            customerConsignee.setIsValid("1");
            customerConsignee.setId(idWorker.nextId() + "").preInsert(user.getId());
            this.customerConsigneeMapper.insert(customerConsignee);
        }

        Customer cust = this.customerMapper.selectById(data.getCustomerNo());

        if(StringUtils.isNull(cust)){
            cust = new Customer();
            cust.setId(data.getCustomerNo()).preInsert(user.getId());
            cust.setCustomerName(data.getDepartureUnit());
            cust.setCustomerType("warehouse");
            cust.setDistrict(data.getPickUpAddress());
            cust.setLocationCode(tBmLocationVo.getTreeIds());
            customerMapper.insert(cust);
        }


        TbWmsMaterialDelivery tbWmsMaterialDelivery = new TbWmsMaterialDelivery();
        // 新增运单主表信息
        if(StringUtils.isNull(tbWmsMaterialDelivery.getOrderNo())){
            String orderNo = tBmsAllGeneralSeqTabService.generateNo("materialDelivery");
            tbWmsMaterialDelivery.setOrderNo("R".concat(orderNo));
        }
        tbWmsMaterialDelivery.setCustomerNo("1000");
        tbWmsMaterialDelivery.setConsignee("");
        tbWmsMaterialDelivery.setCustomerName(data.getCustomerName());
        tbWmsMaterialDelivery.setWarehouseCode(warehouseId);
        tbWmsMaterialDelivery.setStatus("created");
        tbWmsMaterialDelivery.setId(idWorker.nextId() + "").preInsert(user.getId());
        tbWmsMaterialDeliveryMapper.insert(tbWmsMaterialDelivery);

        TbWmsMaterialDeliveryLine entity = new TbWmsMaterialDeliveryLine();
        BeanUtils.copyProperties(data, entity);
        entity.setDeliveryWarehouseCode(warehouseId);
        //entity.setConsignee(customerConsignee.getId());
        entity.setConsigneeAddress(customerConsignee.getConsigneeAddress());
        /*entity.setConsigneeName(customerConsignee.getConsigneeName());
        entity.setConsigneePhoneNo(customerConsignee.getLinkManMobile());*/
        entity.setStatus("created");
        entity.setOrderNo(tbWmsMaterialDelivery.getOrderNo());
        entity.setVehicleLoadType(tWhWarehouseCustomerMaterial.getMaterialType());
        entity.setDeliveryId(tbWmsMaterialDelivery.getId());
        entity.setFreightQuantity(new BigDecimal(1));
        entity.setDeliveryQuantity(new BigDecimal(1));
        entity.setQuantity(1.00);
        entity.setSite(user.getOrgId());
        entity.setReceivedLineId(receiptVo.getItemList().get(0).getId());
        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        entity.setDeliveryType("vehicle");
        entity.setShipByPackOrqty("qty");
        entity.setWeight(Double.valueOf("1"));
        entity.setPickUpWarehouseNo(warehouseId);
        entity.setLocationNo(receiptVo.getItemList().get(0).getLocationNo());
        entity.setMaterialName(receiptVo.getItemList().get(0).getMaterialName());
        entity.setRequestDeliveryTime(data.getEstPickUpTime());
        entity.setDeliveryNo(data.getPickupVoucherList());
        if(tbWmsMaterialInLocationList.size()>0){
            entity.setMaterialVehicleInLocationId(tbWmsMaterialInLocationList.get(0).getId());
        }

        this.tbWmsMaterialDeliveryLineMapper.insert(entity);


        receiptVo.getItemList().get(0).setStatus(WmsInStatusEnum.outPlaned.getValue());
        receiptVo.getItemList().get(0).setUpdateBy(user.getId());
        TbWmsMaterialReceiptLine line1 = new TbWmsMaterialReceiptLine();
        BeanUtils.copyProperties(receiptVo.getItemList().get(0), line1);
        tbWmsMaterialReceiptLineMapper.updateById(line1);


        TbWmsMaterialReceipt receipt = new TbWmsMaterialReceipt();
        BeanUtils.copyProperties(receiptVo, receipt);
        receipt.setStatus(WmsInStatusEnum.outPlaned.getValue());
        receipt.preUpdate(user.getId());
        this.tbWmsMaterialReceiptMapper.updateById(receipt);
        return entity.getId();
    }

    private TFoTransitRouteVo getCarrier(DispatchImportOrderItemVo data){
        TFoTransitRouteSearchParam params = new TFoTransitRouteSearchParam();
        params.setCarrierName(data.getCarrierName());
        params.setRouteType("carrierType");
        TFoTransitRouteVo tFoTransitRouteVo = iTFoTransitRouteService.findByCarrierName(params);
        return tFoTransitRouteVo;
    }







    /**
     * 处理详细地址拆分省 市 区 地址的转换关系
     *
     * @param detailAddress
     * @return
     */
    public String[] convertDetailAddressToPCD(String detailAddress) {
        String[] r = new String[4];
        try {
            String tempStr = detailAddress;
            String province = null;
            int provinceIdx = processProvince(tempStr);
            if (provinceIdx > -1) {
                province = tempStr.substring(0, provinceIdx + 1);
                tempStr = tempStr.substring(provinceIdx + 1);
            }
            String city = null;
            int cityIdx = processCity(tempStr);
            if (cityIdx > -1) {
                city = tempStr.substring(0, cityIdx + 1);
                tempStr = tempStr.substring(cityIdx + 1);
            }
            String county = null;
            int countyIdx = processCounty(tempStr);
            if (countyIdx > -1) {
                county = tempStr.substring(0, countyIdx + 1);
                tempStr = tempStr.substring(countyIdx + 1);
            }
            String street = tempStr;
            r[0] = province;
            r[1] = city;
            r[2] = county;
            r[3] = street;
        } catch (Exception e) {
            // 报错就直接返回r 为空即可。无法正常转义
        }

        return r;
    }

    // (?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)
    private int processProvince(String s) {
        int[] idxs = new int[3];
        int provinceIdx = -1;
        if ((provinceIdx = s.indexOf("省")) > -1)
            idxs[0] = provinceIdx;
        provinceIdx = -1;
        if ((provinceIdx = s.indexOf("市")) > -1)
            idxs[1] = provinceIdx;
        provinceIdx = -1;
        if ((provinceIdx = s.indexOf("区")) > -1)
            idxs[2] = provinceIdx;
        Arrays.sort(idxs);
        for (int i = 0; i < idxs.length; i++) {
            int j = idxs[i];
            if (j > 0) {
                return j;
            }
        }

        return provinceIdx;
    }

    // (?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)
    private int processCity(String s) {
        int[] idxs = new int[7];
        int cityIdx = -1;
        if ((cityIdx = s.indexOf("县")) > -1)
            idxs[0] = cityIdx;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("自治州")) > -1)
            idxs[1] = cityIdx + 2;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("市辖区")) > -1)
            idxs[2] = cityIdx + 2;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("市")) > -1)
            idxs[3] = cityIdx;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("区")) > -1)
            idxs[4] = cityIdx;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("地区")) > -1)
            idxs[5] = cityIdx + 1;
        cityIdx = -1;
        if ((cityIdx = s.indexOf("盟")) > -1)
            idxs[6] = cityIdx;

        Arrays.sort(idxs);

        for (int i = 0; i < idxs.length; i++) {
            int j = idxs[i];
            if (j > 0) {
                return j;
            }
        }

        return cityIdx;
    }

    // (?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)
    private int processCounty(String s) {
        int[] idxs = new int[6];
        int countyIdx = -1;
        if ((countyIdx = s.indexOf("县")) > -1)
            idxs[0] = countyIdx;
        countyIdx = -1;
        if ((countyIdx = s.indexOf("旗")) > -1)
            idxs[1] = countyIdx;
        countyIdx = -1;
        if ((countyIdx = s.indexOf("海域")) > -1)
            idxs[2] = countyIdx + 1;
        countyIdx = -1;
        if ((countyIdx = s.indexOf("市")) > -1)
            idxs[3] = countyIdx;
        countyIdx = -1;
        if ((countyIdx = s.indexOf("区")) > -1)
            idxs[4] = countyIdx;
        countyIdx = -1;
        if ((countyIdx = s.indexOf("岛")) > -1)
            idxs[5] = countyIdx;
        Arrays.sort(idxs);
        for (int i = 0; i < idxs.length; i++) {
            int j = idxs[i];
            if (j > 0) {
                return j;
            }
        }

        return countyIdx;
    }

}
